﻿/*
 *Author: Jeff Liu 
 *
 *Under MIT License
 *jebberwocky@gmail.com
 */
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using CtpGglPlaces.Interface;
using CtpGgl.API;
using CtpGgl.Interface;

namespace CtpGglPlaces.Core
{

    /// <summary>
    /// Class for accessing Google Places API
    /// Author: Jeff Liu
    /// Date: 05/12/2011
    /// Refer: http://code.google.com/apis/maps/documentation/places/
    /// </summary>
    public class GooglePlacesApi : WebUtil
    {
        /// <summary>
        /// key for google language translate
        /// </summary>
        public const String GOOGLE_PLACES_API_URL = "https://maps.googleapis.com/maps/api/place/search/";

        public const String GOOGLE_PLACES_DETAIL_URL = "https://maps.googleapis.com/maps/api/place/details/";

        public static String SendRequest(AbstractUrlParameter param, String format)
        {
            if (!param.isValid())
                throw new ArgumentException();
            return WebRequest(param.getUrl(format));
        }
    }

    public abstract class AbstractUrlParameter
    {
        private Dictionary<String, String> param = new Dictionary<string, string>();

        private IGoogleKeyProvider keyProvider;

        private bool sensor;

        public IGoogleKeyProvider KeyProvider {
            set { keyProvider = value; setParam("key", keyProvider.GetKey("places")); } 
            get { return keyProvider; } }

        protected void setParam(string key, string value)
        {
            if (param.Keys.Contains(key))
                param[key] = value;
            else
                param.Add(key, value);
        }

        public abstract bool isValid();

        public abstract String getUrl(String format);

        public string getParams()
        {
            StringBuilder sb = new StringBuilder();
            foreach (String key in param.Keys)
            {
                sb.Append(String.Format("{0}={1}&", key, param[key]));
            }
            return sb.ToString().TrimEnd('&');
        }

        public bool Sensor { set { this.sensor = value; setParam("sensor", value.ToString().ToLower()); } get { return this.sensor; } }
    }

    public class SearchUrlParameter : AbstractUrlParameter
    {
        IGeoPoint location;
        double radius;

        public IGeoPoint Location
        {
            set
            {
                if (value != null)
                {
                    this.location = value;
                    setParam("location", value.ToString());
                }
            }
            get{return this.location;}
        }

        public double Radius { set { this.radius = value; setParam("radius", ((int)value).ToString()); } get { return this.radius; } }

        public override String getUrl(String format)
        {
            String url = GooglePlacesApi.GOOGLE_PLACES_API_URL + format + "?" + this.getParams();
            return url;
        }

        public override bool isValid()
        {
            bool flag = false;
            if(location !=null && radius >0)
                flag = true;
            return flag;
        }
    }

    public class DetailUrlParameter : AbstractUrlParameter
    {
        private string reference;

        public String Reference 
        {
            set { this.reference = value; setParam("reference", value); }
            get { return this.reference; }
        }

        public override bool isValid()
        {
            bool flag = false;
            if (!String.IsNullOrEmpty(this.reference))
                flag = true;
            return flag;
        }

        public override string getUrl(string format)
        {
            String url = GooglePlacesApi.GOOGLE_PLACES_DETAIL_URL + format + "?" + this.getParams();
            return url;
        }
    }
}
